From 856ee02fe4f7d8d059dcd9d2ff7b1ca7586b2451 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Mon, 27 Mar 2006 18:46:38 +0000 Subject: [PATCH] Make the poll func work with real file descriptors. We do this by creating 2006-03-27 Anders Carlsson * gdk/quartz/gdkevents-quartz.c: (select_thread_func): (got_fd_activity): (poll_func): (gdk_event_translate): Make the poll func work with real file descriptors. We do this by creating a thread which calls poll and then signals the main thread using a run loop source. * gtk/gtkclipboard-quartz.c: (-[GtkClipboardOwner pasteboard:provideDataForType:]): Remove debugging output --- ChangeLog | 15 ++++ ChangeLog.pre-2-10 | 15 ++++ gdk/quartz/gdkevents-quartz.c | 143 +++++++++++++++++++++++++++++++++- gtk/gtkclipboard-quartz.c | 2 - 4 files changed, 170 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 89460dd916..40eb0f7797 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2006-03-27 Anders Carlsson + + * gdk/quartz/gdkevents-quartz.c: + (select_thread_func): + (got_fd_activity): + (poll_func): + (gdk_event_translate): + Make the poll func work with real file descriptors. + We do this by creating a thread which calls poll and then + signals the main thread using a run loop source. + + * gtk/gtkclipboard-quartz.c: + (-[GtkClipboardOwner pasteboard:provideDataForType:]): + Remove debugging output + 2006-03-27 Matthias Clasen * gtk/gtkmnemonichash.c (_gtk_mnemonic_hash_activate): Check that diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 89460dd916..40eb0f7797 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,18 @@ +2006-03-27 Anders Carlsson + + * gdk/quartz/gdkevents-quartz.c: + (select_thread_func): + (got_fd_activity): + (poll_func): + (gdk_event_translate): + Make the poll func work with real file descriptors. + We do this by creating a thread which calls poll and then + signals the main thread using a run loop source. + + * gtk/gtkclipboard-quartz.c: + (-[GtkClipboardOwner pasteboard:provideDataForType:]): + Remove debugging output + 2006-03-27 Matthias Clasen * gtk/gtkmnemonichash.c (_gtk_mnemonic_hash_activate): Check that diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c index e5470bbc7f..97c62f2993 100644 --- a/gdk/quartz/gdkevents-quartz.c +++ b/gdk/quartz/gdkevents-quartz.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "gdkscreen.h" #include "gdkprivate-quartz.h" @@ -117,17 +119,114 @@ static GSourceFuncs event_funcs = { static GPollFunc old_poll_func; +static pthread_t select_thread = 0; +static int wakeup_pipe[2]; +static pthread_mutex_t pollfd_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER; +static GPollFD *pollfds; +static GPollFD *pipe_pollfd; +static guint n_pollfds; +static CFRunLoopSourceRef select_main_thread_source; +static CFRunLoopRef main_thread_run_loop; + +static void * +select_thread_func (void *arg) +{ + int n_active_fds; + + while (1) + { + pthread_mutex_lock (&pollfd_mutex); + pthread_cond_wait (&ready_cond, &pollfd_mutex); + + n_active_fds = old_poll_func (pollfds, n_pollfds, -1); + if (pipe_pollfd->revents) + { + char c; + int n; + + n = read (pipe_pollfd->fd, &c, 1); + + g_assert (n == 1); + g_assert (c == 'A'); + + n_active_fds --; + } + pthread_mutex_unlock (&pollfd_mutex); + + if (n_active_fds) + { + /* We have active fds, signal the main thread */ + CFRunLoopSourceSignal (select_main_thread_source); + if (CFRunLoopIsWaiting (main_thread_run_loop)) + CFRunLoopWakeUp (main_thread_run_loop); + } + } +} + +static void +got_fd_activity (void *info) +{ + NSEvent *event; + + /* Post a message so we'll break out of the message loop */ + event = [NSEvent otherEventWithType: NSApplicationDefined + location: NSZeroPoint + modifierFlags: 0 + timestamp: 0 + windowNumber: 0 + context: nil + subtype: 0 + data1: 0 + data2: 0]; + + [NSApp postEvent:event atStart:YES]; +} + static gint poll_func (GPollFD *ufds, guint nfds, gint timeout_) { NSEvent *event; NSDate *limit_date; int n_active = 0; + int i; GDK_QUARTZ_ALLOC_POOL; - /* FIXME: Support more than one pollfd */ - g_assert (nfds == 1); + if (nfds > 1) + { + if (!select_thread) { + /* Create source used for signalling the main thread */ + main_thread_run_loop = CFRunLoopGetCurrent (); + CFRunLoopSourceContext source_context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, got_fd_activity }; + select_main_thread_source = CFRunLoopSourceCreate (NULL, 0, &source_context); + CFRunLoopAddSource (main_thread_run_loop, select_main_thread_source, kCFRunLoopDefaultMode); + + pipe (wakeup_pipe); + pthread_create (&select_thread, NULL, select_thread_func, NULL); + } + + pthread_mutex_lock (&pollfd_mutex); + n_pollfds = nfds; + g_free (pollfds); + pollfds = g_memdup (ufds, sizeof (GPollFD) * nfds); + + /* We cheat and use the fake fd for our pipe */ + for (i = 0; i < nfds; i++) + { + if (pollfds[i].fd == -1) + { + pipe_pollfd = &pollfds[i]; + pollfds[i].fd = wakeup_pipe[0]; + pollfds[i].events = G_IO_IN; + } + } + + pthread_mutex_unlock (&pollfd_mutex); + + /* Start our thread */ + pthread_cond_signal (&ready_cond); + } if (timeout_ == -1) limit_date = [NSDate distantFuture]; @@ -140,6 +239,45 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_) untilDate: limit_date inMode: NSDefaultRunLoopMode dequeue: YES]; + + if (event) + { + if ([event type] == NSApplicationDefined) + { + + pthread_mutex_lock (&pollfd_mutex); + + for (i = 0; i < n_pollfds; i++) + { + if (ufds[i].fd == -1) + continue; + + g_assert (ufds[i].fd == pollfds[i].fd); + g_assert (ufds[i].events == pollfds[i].events); + + if (pollfds[i].revents) + { + ufds[i].revents = pollfds[i].revents; + n_active ++; + } + } + + pthread_mutex_unlock (&pollfd_mutex); + + event = [NSApp nextEventMatchingMask: NSAnyEventMask + untilDate: [NSDate distantPast] + inMode: NSDefaultRunLoopMode + dequeue: YES]; + + } + } + + /* There were no active fds, break out of the other thread's poll() */ + if (n_active == 0 && wakeup_pipe[1]) + { + char c = 'A'; + write (wakeup_pipe[1], &c, 1); + } if (event) { @@ -1163,7 +1301,6 @@ create_key_event (GdkWindow *window, NSEvent *nsevent) static gboolean gdk_event_translate (NSEvent *nsevent) { - NSWindow *nswindow = [nsevent window]; GdkWindow *window; GdkFilterReturn result; GdkEvent *event; diff --git a/gtk/gtkclipboard-quartz.c b/gtk/gtkclipboard-quartz.c index 9a79c25947..448eb7de6c 100644 --- a/gtk/gtkclipboard-quartz.c +++ b/gtk/gtkclipboard-quartz.c @@ -106,8 +106,6 @@ struct _GtkClipboardClass _gtk_quartz_set_selection_data_for_pasteboard (clipboard->pasteboard, &selection_data); g_free (selection_data.data); - - NSLog(@"Provide data for %@", type); } - (void)pasteboardChangedOwner:(NSPasteboard *)sender -- 2.30.2